//
//  AppDelegate+JPush.m
//  TongGuanLease
//
//  Created by Henghuitong on 2022/7/26.
//

#import "AppDelegate+JPush.h"
#import "UITabBarItem+PPBadgeView.h"
#import "TGTabBarVC.h"
#import "LoginVC.h"

static NSString *JPushAppKey = @"cf8cf6ad5dd004a34a808459"; //极光
static NSString *channel = @"App Store";

//配置推送环境  0 (默认值)表示采用的是开发证书 1 表示采用生产证书发布应用
#ifdef DEBUG // 开发
static BOOL const isProduction = FALSE; // 极光FALSE为开发环境
#else // 生产
static BOOL const isProduction = TRUE; // 极光TRUE为生产环境
#endif


@interface AppDelegate ()<JPUSHRegisterDelegate,UNUserNotificationCenterDelegate>

@end

@implementation AppDelegate (JPush)

#pragma mark - 注册极光推送

- (void)regisJPushWithApplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    NSLog(@"isProduction==%d",isProduction);
    //【初始化sdk】
    //【注册通知】通知回调代理
    // 3.0.0及以后版本注册
    JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
    if (@available(iOS 12.0, *)) {
        // iOS 12 及其以上系统运行
      entity.types = JPAuthorizationOptionAlert|JPAuthorizationOptionBadge|JPAuthorizationOptionSound|JPAuthorizationOptionProvidesAppNotificationSettings;
    } else {
      entity.types = JPAuthorizationOptionAlert|JPAuthorizationOptionBadge|JPAuthorizationOptionSound;
    }
    
    [JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
    //如不需要使用IDFA，advertisingIdentifier 可为nil
    [JPUSHService setupWithOption:launchOptions
                           appKey:JPushAppKey
                          channel:channel
                 apsForProduction:isProduction
            advertisingIdentifier:nil];
    
    
    // App 未启动状态：apn 内容获取
//    NSDictionary *remoteNotification = [launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKey];
//    if(remoteNotification != nil)
//    {
//        NSLog(@"App未启动状态 收到远程通知:%@", remoteNotification);
//        [self receiveNoticationHandleWithUserInfo:remoteNotification];
//    }
    
    
//    [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
//    [JPUSHService resetBadge];
    

//    [JPUSHService getAlias:^(NSInteger iResCode, NSString *iAlias, NSInteger seq) {
//        NSLog(@"别名回调 %@",[NSString stringWithFormat:@"iResCode:%ld, \niAlias: %@, \nseq: %ld\n", (long)iResCode, iAlias, (long)seq]);
//
//    } seq:0];
    
}

#pragma mark - 别名
//设置别名
+ (void)setAlias:(NSString *)aliasName
{
    NSLog(@"getAliasSeq======%ld",[TGUserModel getUserEntity].getAliasSeq);
    [JPUSHService setAlias:aliasName completion:^(NSInteger iResCode, NSString *iAlias, NSInteger seq) {
        
//        if (iResCode == 0) {
//            UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"别名设置成功" message:nil preferredStyle:UIAlertControllerStyleAlert];
//            UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
//
//            }];
//
//            [alertVC addAction:sureAction];
//            [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertVC animated:YES completion:nil];
//        }
        NSLog(@"设置别名回调 %@",[NSString stringWithFormat:@"iResCode:%ld, \niAlias: %@, \nseq: %ld\n", (long)iResCode, iAlias, (long)seq]);
        
    } seq:[TGUserModel getUserEntity].getAliasSeq];
    
}

//清除别名
+ (void)deleteAlias
{
    NSLog(@"getAliasSeq======%ld",[TGUserModel getUserEntity].getAliasSeq);

    [JPUSHService deleteAlias:^(NSInteger iResCode, NSString *iAlias, NSInteger seq) {
       
        NSLog(@"清除别名回调 %@",[NSString stringWithFormat:@"iResCode:%ld, \niAlias: %@, \nseq: %ld\n", (long)iResCode, iAlias, (long)seq]);
        //清除登录数据
//        [TGUserModel remove];
        
    } seq:[TGUserModel getUserEntity].getAliasSeq];
    
}

#pragma mark - 设置角标
//设置角标
+ (void)setJPshBadgeWithBadge:(NSInteger)badge
{
    if(badge >= 0)
    {
        if(badge == 0)
        {
            [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
            [[UIApplication sharedApplication] cancelAllLocalNotifications];
            [JPUSHService resetBadge];
            
        }else
        {
            [UIApplication sharedApplication].applicationIconBadgeNumber = badge;
            [JPUSHService setBadge:badge];
        }
    }
   
    
}


- (void)setJPshBadge
{
    NSInteger badge=[[UIApplication sharedApplication] applicationIconBadgeNumber];
    if(badge > 0)
    {
        badge--;
        [UIApplication sharedApplication].applicationIconBadgeNumber=badge;
    }
    if(badge==0)
    {
        [UIApplication sharedApplication].applicationIconBadgeNumber=0;
        [[UIApplication sharedApplication] cancelAllLocalNotifications];
//        [[UNUserNotificationCenter currentNotificationCenter]removeAllPendingNotificationRequests];
    }
    [JPUSHService setBadge:badge];

}

#pragma mark - 处理推送消息
-(void)receiveNoticationHandleWithUserInfo:(NSDictionary *)userInfo
{
    NSLog(@"userInfo===%@", userInfo);
//    NSString *contentType = [NSString stringWithFormat:@"%@",R( userInfo[@"contentType"])];

    [self setJPshBadge];
    [[NSNotificationCenter defaultCenter] postNotificationName:KNotificationWithRefresheEventCount object:nil];
    
    if([UIApplication sharedApplication].applicationState == UIApplicationStateActive) {
        NSLog(@"前台");
        [self jumpToIndex:0];
    } else if([UIApplication sharedApplication].applicationState == UIApplicationStateInactive) {
        NSLog(@"Inactive 收到通知");
        [self jumpToIndex:0];
    } else {
        NSLog(@"后台");
    }

}

- (void)jumpToIndex:(NSInteger)index {
    if(![self.getCurrentVC isKindOfClass: [LoginVC class]]) {
        NSLog(@"已经登录");
        
        if(self.getCurrentVC.navigationController.viewControllers.count > 1) {
            [self.getCurrentVC.navigationController popToRootViewControllerAnimated:YES];
        }
        [TGGCD executeAfterTime:1 task:^{
            TGTabBarVC *tabVC = (TGTabBarVC *)self.window.rootViewController;
            tabVC.selectedIndex = index;
//            [tabVC.tabBarItem pp_showBadge];
        }];
        
    }
}


- (UIViewController *)getCurrentViewController{
    UIViewController *vc = [self topVC:[UIApplication sharedApplication].keyWindow.rootViewController]; //拿到当前页面的VC
    return vc;
}

- (UIViewController *)topVC:(UIViewController *)rootViewController
{
    if ([rootViewController isKindOfClass:[UITabBarController class]]) {
        UITabBarController *tab = (UITabBarController *)rootViewController;
        return [self topVC:tab.selectedViewController];
    }else if ([rootViewController isKindOfClass:[UINavigationController class]]){
        UINavigationController *navc = (UINavigationController *)rootViewController;
        return [self topVC:navc.visibleViewController];
    }else if (rootViewController.presentedViewController){
        UIViewController *pre = (UIViewController *)rootViewController.presentedViewController;
        return [self topVC:pre];
    }else{
        return rootViewController;
    }
}

#pragma mark - UIApplicationDelegate
- (void)applicationDidEnterBackground:(UIApplication *)application {
    
//    [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
//    [JPUSHService resetBadge];
    
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
   
//    [application setApplicationIconBadgeNumber:0];
//    [application cancelAllLocalNotifications];
//    [JPUSHService resetBadge];

}

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    const unsigned int *tokenBytes = [deviceToken bytes];
    NSString *tokenString = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
                             ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
                             ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
                             ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
    NSLog(@"Device Token: %@", tokenString);
    //sdk注册DeviceToken
    [JPUSHService registerDeviceToken:deviceToken];
    
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
  //Optional
    //实现注册APNs 注册远程通知失败并出现错误
  NSLog(@"注册远程通知失败并出现错误: %@", error);
    
}


#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_7_1
- (void)application:(UIApplication *)application
    didRegisterUserNotificationSettings:
        (UIUserNotificationSettings *)notificationSettings {
}

- (void)application:(UIApplication *)application
    handleActionWithIdentifier:(NSString *)identifier
          forLocalNotification:(UILocalNotification *)notification
             completionHandler:(void (^)())completionHandler {
}

- (void)application:(UIApplication *)application
    handleActionWithIdentifier:(NSString *)identifier
         forRemoteNotification:(NSDictionary *)userInfo
             completionHandler:(void (^)())completionHandler {
}
#endif

/**
 * 方法1: 兼容iOS 3 — iOS 10
 * 过期后，分别由方法4 5来代替处理`用户可见远程通知`，由方法3来代替处理`静默远程通知silent remote notifications`
 * If a remote notification arrives while your app is active, WatchKit calls this method to deliver the notification payload. 即只有当APP处于活跃状态时，收到远程通知，才会触发这个方法。
 * 活跃分为：前台、后台活跃，当处于前台时不显示通知alert，直接触发这个方法(iOS 10之后如果想在前台显示alert，需要实现方法4，iOS10之前，则需要自己发local notification来显示alert)。当处于后台活跃状态时，会显示，点击通知才会触发这个方法
 * 注意：如果实现了方法3，这个方法就不会被回调
*/
- (void)application:(UIApplication *)application
    didReceiveRemoteNotification:(NSDictionary *)userInfo {
  [JPUSHService handleRemoteNotification:userInfo];
    
    [self receiveNoticationHandleWithUserInfo:userInfo];
    
  NSLog(@"iOS6及以下系统，收到通知:%@",userInfo);
}
/**
 * 方法2: 兼容iOS 4 — iOS 10
 * 过期后, 分别由方法4 5来代替处理本地通知
*/
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
    
}


/**
 * 方法3: 兼容iOS 7及以后
 * Tells the delegate that a background notification has arrived. 即APP处于挂起、kill状态都会触发这个方法。触发 与alert显示情况与方法1相同：处于前台时，不alert，直接调用；挂起或kill状态，点击通知会触发
 * 实现此方法来处理传入的后台通知。当通知到达时，系统会启动您的应用程序或将其从挂起状态唤醒，您的应用程序会收到在后台运行的一小段时间。
 * 可以使用后台执行时间处理通知并下载其相关内容。一旦完成对通知的处理，就必须调用fetchCompletionHandler完成处理程序。您的应用程序有30秒的挂钟时间来处理通知并调用处理程序，时间到了系统会终止您的应用程序。请尽可能快地调用处理程序，因为系统会跟踪应用程序后台通知的运行时间、功耗和数据成本。
 * 后台通知是低优先级的，系统根据目标设备的功率考虑限制这些通知。APNs不保证设备会收到推送通知，而那些在处理后台通知时消耗大量能量或时间的应用程序可能不会收到后台时间来处理未来的通知。
 * 应用程序因为远程通知而启动或恢复，也将调用此方法。注意，此方法与方法1冲突，如果实现了此方法，则不会调用方法1
 */
- (void)application:(UIApplication *)application
    didReceiveRemoteNotification:(NSDictionary *)userInfo
          fetchCompletionHandler:
              (void (^)(UIBackgroundFetchResult))completionHandler {
  [JPUSHService handleRemoteNotification:userInfo];
  NSLog(@"iOS7及以上系统，收到通知:%@", userInfo);
  
    [self receiveNoticationHandleWithUserInfo:userInfo];
  
  if ([[UIDevice currentDevice].systemVersion floatValue]<10.0 || application.applicationState>0) {

  }

  completionHandler(UIBackgroundFetchResultNewData);
    
}


#pragma mark - iOS10: 收到推送消息调用(iOS10是通过Delegate实现的回调)
#pragma mark -JPUSHRegisterDelegate
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
// iOS 10 Support
//iOS 设备收到通知推送（APNs ），用户点击推送通知打开应用时，应用程序根据运行状态进行不同处理：
//当程序在前台时, 收到推送弹出的通知
/**
 * 方法4: 兼容iOS 10及以后
 * 只有当应用程序位于前台时，才会在收到通知时调用该方法。如果方法没有实现，或者没有及时调用处理程序，则前台不会显示通知。应用程序可以选择以声音、徽章、警报和/或在通知列表中显示通知。取决于通知中的信息是否对用户可见
 * 实现了该方法后，方法1 3会收到影响，在前台时，不再是不显示+直接触发方法1 3，而是触发本方法，点击之后触发方法1 3
 *
 * 当 App 处于前台时 展示通知，实现该方法：（若不想展示，则不实现即可）
*/

- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger options))completionHandler {
  NSDictionary * userInfo = notification.request.content.userInfo;
  
  UNNotificationRequest *request = notification.request; // 收到推送的请求
  UNNotificationContent *content = request.content; // 收到推送的消息内容
  
  NSNumber *badge = content.badge;  // 推送消息的角标
  NSString *body = content.body;    // 推送消息体
  UNNotificationSound *sound = content.sound;  // 推送消息的声音
  NSString *subtitle = content.subtitle;  // 推送消息的副标题
  NSString *title = content.title;  // 推送消息的标题
  
  if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
    
      [JPUSHService handleRemoteNotification:userInfo];
    
      NSLog(@"iOS10程序在前台时收到的推送: %@", userInfo);
  
//      [self receiveNoticationHandleWithUserInfo:userInfo];
      
  } else {
    // 判断为本地通知
      
  }
    
  completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert); // 需要执行这个方法，选择是否提醒用户，有Badge、Sound、Alert三种类型可以设置
}



// iOS 10 Support
// 程序关闭后, 通过点击推送弹出的通知
/**
 * 方法5: 兼容iOS 10及以后
 * 当用户通过打开应用程序、取消通知或选择UNNotificationAction来响应通知时，会调用该方法。必须在应用程序从application:didFinishLaunchingWithOptions:返回之前设置delegate。
*/
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler {
  
  NSDictionary * userInfo = response.notification.request.content.userInfo;
  UNNotificationRequest *request = response.notification.request; // 收到推送的请求
  UNNotificationContent *content = request.content; // 收到推送的消息内容
  
  NSNumber *badge = content.badge;  // 推送消息的角标
  NSString *body = content.body;    // 推送消息体
  UNNotificationSound *sound = content.sound;  // 推送消息的声音
  NSString *subtitle = content.subtitle;  // 推送消息的副标题
  NSString *title = content.title;  // 推送消息的标题
  
  if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
    
      [JPUSHService handleRemoteNotification:userInfo];
    
      NSLog(@"点击推送通知: %@", userInfo);
    
      [self receiveNoticationHandleWithUserInfo:userInfo];
      
  } else {
    // 判断为本地通知
  }
  
  completionHandler();  // 系统要求执行这个方法
}

- (void)jpushNotificationAuthorization:(JPAuthorizationStatus)status withInfo:(NSDictionary *)info {
    NSLog(@"接收通知授权状态:%lu, info:%@", status, info);//1001A8100000000F0EBC 
}

#endif

#ifdef __IPHONE_12_0
/**
 * 方法6: 兼容iOS 12及以后
 * 极光的解释：当从应用外部通知界面或通知设置界面进入应用时，该方法将回调。
*/
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center openSettingsForNotification:(UNNotification *)notification {
    if (notification && [notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        //从通知界面直接进入应用
        
    }else{
        //从通知设置界面进入应用
        
    }
  
}
#endif






@end
